/*NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN

	Copyright (c) 2009 Jounayd Id Salah.
	All rights reserved.

	This file is part of Blacklib.

	Blacklib is free software: you can redistribute it and/or modify it under the 
	terms of the GNU Lesser General Public License as published by the Free Software 
	Foundation, either version 3 of the License, or (at your option) any later version.
	Blacklib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; 
	without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
	PURPOSE.  See the GNU Lesser General Public License for more details.
	You should have received a copy of the GNU Lesser General Public License along with 
	Blacklib.  If not, see <http://www.gnu.org/licenses/>.
*/
//NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN

#include "maths/vector.h"

namespace black
{
	//***************************************************************
	// Vec3
	//***************************************************************

	//__________________________________________________________________________
	bALIGN16 const vec3 vec3::ZERO		= vec3( 0.f, 0.f, 0.f ); 
	bALIGN16 const vec3 vec3::ONE		= vec3( 1.f, 1.f, 1.f );
	bALIGN16 const vec3 vec3::X_AXIS	= vec3( 1.f, 0.f, 0.f );
	bALIGN16 const vec3 vec3::Y_AXIS	= vec3( 0.f, 1.f, 0.f );
	bALIGN16 const vec3 vec3::Z_AXIS	= vec3( 0.f, 0.f, 1.f );
	bALIGN16 const vec3 vec3::NX_AXIS	= vec3( -1.f, 0.f, 0.f );
	bALIGN16 const vec3 vec3::NY_AXIS	= vec3( 0.f, -1.f, 0.f );
	bALIGN16 const vec3 vec3::NZ_AXIS	= vec3( 0.f, 0.f, -1.f );

	//__________________________________________________________________________
	void vec3::slerp( const vec3& v, float fCoef )
	{
		assert( this->isUnit() );
		assert( v.isUnit() );
		assert( fCoef >= 0.f );
		assert( fCoef <= 1.f );

		const float fAngle = this->angle( v );
		if ( abs( fAngle ) < fEPSILON )
			return;
		const float fWeightedAngle = fCoef * fAngle;
		const float fSinAngle		= sin( fAngle );
		const float fSinT			= sin( fWeightedAngle );
		const float fSinTOp			= sin( fAngle - fWeightedAngle );

		assert( fSinAngle != 0.f );

		*this *= fSinTOp;
		*this += v * fSinT;
		*this /= fSinAngle;
		// *pOut = ( fSinTOp * *pVUnitA + fSinT * *pVUnitB ) / fSinAngle;
	}

	//***************************************************************
	// vec3_128
	//***************************************************************

	//__________________________________________________________________________
	bALIGN16 const vec3_128 vec3_128::ZERO		= vec3_128( 0.f, 0.f, 0.f ); 
	bALIGN16 const vec3_128 vec3_128::ONE		= vec3_128( 1.f, 1.f, 1.f );
	bALIGN16 const vec3_128 vec3_128::X_AXIS	= vec3_128( 1.f, 0.f, 0.f );
	bALIGN16 const vec3_128 vec3_128::Y_AXIS	= vec3_128( 0.f, 1.f, 0.f );
	bALIGN16 const vec3_128 vec3_128::Z_AXIS	= vec3_128( 0.f, 0.f, 1.f );
	bALIGN16 const vec3_128 vec3_128::NX_AXIS	= vec3_128( -1.f, 0.f, 0.f );
	bALIGN16 const vec3_128 vec3_128::NY_AXIS	= vec3_128( 0.f, -1.f, 0.f );
	bALIGN16 const vec3_128 vec3_128::NZ_AXIS	= vec3_128( 0.f, 0.f, -1.f );

	//***************************************************************
	// vec4
	//***************************************************************

	//__________________________________________________________________________
	bALIGN16 const vec4 vec4::ZERO		= vec4( 0.f, 0.f, 0.f, 1.f ); 
	bALIGN16 const vec4 vec4::ONE		= vec4( 1.f, 1.f, 1.f, 1.f );
	bALIGN16 const vec4 vec4::X_AXIS	= vec4( 1.f, 0.f, 0.f, 1.f );
	bALIGN16 const vec4 vec4::Y_AXIS	= vec4( 0.f, 1.f, 0.f, 1.f );
	bALIGN16 const vec4 vec4::Z_AXIS	= vec4( 0.f, 0.f, 1.f, 1.f );
	bALIGN16 const vec4 vec4::NX_AXIS	= vec4( -1.f, 0.f, 0.f, 1.f );
	bALIGN16 const vec4 vec4::NY_AXIS	= vec4( 0.f, -1.f, 0.f, 1.f );
	bALIGN16 const vec4 vec4::NZ_AXIS	= vec4( 0.f, 0.f, -1.f, 1.f );

	//***************************************************************
	// vec4_128
	//***************************************************************

	//__________________________________________________________________________
	bALIGN16 const vec4_128 vec4_128::ZERO		= vec4_128( 0.f, 0.f, 0.f, 1.f ); 
	bALIGN16 const vec4_128 vec4_128::ONE		= vec4_128( 1.f, 1.f, 1.f, 1.f );
	bALIGN16 const vec4_128 vec4_128::X_AXIS	= vec4_128( 1.f, 0.f, 0.f, 1.f );
	bALIGN16 const vec4_128 vec4_128::Y_AXIS	= vec4_128( 0.f, 1.f, 0.f, 1.f );
	bALIGN16 const vec4_128 vec4_128::Z_AXIS	= vec4_128( 0.f, 0.f, 1.f, 1.f );
	bALIGN16 const vec4_128 vec4_128::NX_AXIS	= vec4_128( -1.f, 0.f, 0.f, 1.f );
	bALIGN16 const vec4_128 vec4_128::NY_AXIS	= vec4_128( 0.f, -1.f, 0.f, 1.f );
	bALIGN16 const vec4_128 vec4_128::NZ_AXIS	= vec4_128( 0.f, 0.f, -1.f, 1.f );
}
